﻿//#include <iostream>
//#include <vector>
//using namespace std;

// 1 多项式输出
// https://www.luogu.com.cn/problem/P1067

//int main()
//{
//    int n; cin >> n;
//
//    for (int i = n; i >= 0; i--)
//    {
//        int a; cin >> a;
//        if (a == 0) continue;
//
//        if (a < 0) cout << '-';
//        else if (i != n) cout << '+';
//        a = abs(a);
//        if (a != 1 || (a == 1 && i == 0)) cout << a;
//        if (i == 0) continue;
//        else if (i == 1) cout << 'x';
//        else cout << "x^" << i;
//    }
//
//    return 0;
//}

// 2 蛇形⽅阵
// https://www.luogu.com.cn/problem/P5731
//#include <iostream>
//using namespace std;
//const int N = 15;
//// 定义 右，下，左，上 四个⽅向
//int dx[] = { 0, 1, 0, -1 };
//int dy[] = { 1, 0, -1, 0 };
//int arr[N][N];
//int main()
//{
//    int n; cin >> n;
//    // 模拟填数过程
//    int x = 1, y = 1; // 初始位置
//    int cnt = 1; // 当前位置要填的数
//    int pos = 0; // 当前的⽅向
//    while (cnt <= n * n)
//    {
//        arr[x][y] = cnt;
//        // 计算下⼀个位置
//        int a = x + dx[pos], b = y + dy[pos];
//        // 判断是否越界
//        if (a < 1 || a > n || b < 1 || b > n || arr[a][b])
//        {
//            // 更新出正确的该⾛的位置
//            pos = (pos + 1) % 4;
//            a = x + dx[pos], b = y + dy[pos];
//        }
//        x = a, y = b;
//        cnt++;
//    }
//    // 输出
//    for (int i = 1; i <= n; i++)
//    {
//        for (int j = 1; j <= n; j++)
//        {
//            printf("%3d", arr[i][j]);
//        }
//        puts("");
//    }
//    return 0;
//}

// 3 字符串的展开
// https://www.luogu.com.cn/problem/P1098
//#include <iostream>
//#include <algorithm>
//using namespace std;
//int p1, p2, p3, n;
//string s;
//string ret;
//// 判断是否是数字字符
//bool isdig(char ch)
//{
//    return ch >= '0' && ch <= '9';
//}
//// 判断是否是⼩写字⺟
//bool islet(char ch)
//{
//    return ch >= 'a' && ch <= 'z';
//}
//// 把 [left, right] 之间的字符展开
//// left, right 这两个字符是不做处理
//void add(char left, char right)
//{
//    string t;
//    // 遍历中间的字符
//    for (char ch = left + 1; ch < right; ch++)
//    {
//        char tmp = ch;
//        // 处理 p1
//        if (p1 == 2 && islet(tmp)) tmp -= 32; // ⼩写变⼤写
//        else if (p1 == 3) tmp = '*'; // 变成星号
//        // 处理 p2
//        for (int i = 0; i < p2; i++)
//        {
//            t += tmp;
//        }
//    }
//    // 处理 p3
//    if (p3 == 2) reverse(t.begin(), t.end());
//    ret += t;
//}
//
//int main()
//{
//    cin >> p1 >> p2 >> p3 >> s;
//    n = s.size();
//    for (int i = 0; i < n; i++)
//    {
//        char ch = s[i];
//        if (s[i] != '-' || i == 0 || i == n - 1) ret += ch;
//        else
//        {
//            char left = s[i - 1], right = s[i + 1];
//            // 判断是否展开
//            if (isdig(left) && isdig(right) && right > left ||
//                islet(left) && islet(right) && right > left)
//            {
//                // 展开
//                add(left, right);
//            }
//            else
//            {
//                ret += ch;
//            }
//        }
//    }
//    cout << ret << endl;
//    return 0;
//}

// ⾼精度加法
//  https://www.luogu.com.cn/problem/P1601
//#include <iostream>
//using namespace std;
//const int N = 1e6 + 10;
//int a[N], b[N], c[N];
//int la, lb, lc;
//// ⾼精度加法的模版 - c = a + b;
//void add(int c[], int a[], int b[])
//{
//	for (int i = 0; i < lc; i++)
//	{
//		c[i] += a[i] + b[i]; // 对应位相加，再加上进位
//		c[i + 1] += c[i] / 10; // 处理进位
//		c[i] %= 10; // 处理余数
//	}
//	if (c[lc]) lc++;
//}
//
//int main()
//{
//	string x, y; cin >> x >> y;
//	// 1. 拆分每⼀位，逆序放在数组中
//	la = x.size(); lb = y.size(); lc = max(la, lb);
//	for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
//	for (int i = 0; i < lb; i++) b[lb - 1 - i] = y[i] - '0';
//	// 2. 模拟加法的过程
//	add(c, a, b); // c = a + b
//	// 输出结果
//	for (int i = lc - 1; i >= 0; i--) cout << c[i];
//	return 0;
//}
 

// ⾼精度减法
// https://www.luogu.com.cn/problem/P2142
//#include <iostream>
//using namespace std;
//const int N = 1e6 + 10;
//int a[N], b[N], c[N];
//int la, lb, lc;
//// ⽐⼤⼩
//bool cmp(string& x, string& y)
//{
//	// 先⽐较⻓度
//	if (x.size() != y.size()) return x.size() < y.size();
//	// 再按照 字典序 的⽅式⽐较
//	return x < y;
//}
//// ⾼精度减法的模板 - c = a - b
//void sub(int c[], int a[], int b[])
//{
//	for (int i = 0; i < lc; i++)
//	{
//		c[i] += a[i] - b[i]; // 对应位相减，然后处理借位
//		if (c[i] < 0)
//		{
//			c[i + 1] -= 1; // 借位
//			c[i] += 10;
//		}
//	}
//	// 处理前导零
//	while (lc > 1 && c[lc - 1] == 0) lc--;
//}
//int main()
//{
//	string x, y; cin >> x >> y;
//	// ⽐⼤⼩
//	if (cmp(x, y))
//	{
//		swap(x, y);
//		cout << '-';
//	}
//	// 1. 拆分每⼀位，然后逆序放在数组中
//	la = x.size(); lb = y.size(); lc = max(la, lb);
//	for (int i = 0; i < la; i++) a[la - i - 1] = x[i] - '0';
//	for (int i = 0; i < lb; i++) b[lb - i - 1] = y[i] - '0';
//	// 2. 模拟减法的过程
//	sub(c, a, b); // c = a - b
//	// 输出结果
//	for (int i = lc - 1; i >= 0; i--) cout << c[i];
//	return 0;
//}

// ⾼精度乘法
// https://www.luogu.com.cn/problem/P1303
//#include <iostream>
//using namespace std;
//const int N = 1e6 + 10;
//int a[N], b[N], c[N];
//int la, lb, lc;
//// ⾼精度乘法的模版 - c = a * b
//void mul(int c[], int a[], int b[])
//{
//	// ⽆进位相乘,然后相加
//	for (int i = 0; i < la; i++)
//	{
//		for (int j = 0; j < lb; j++)
//		{
//			c[i + j] += a[i] * b[j];
//		}
//	}
//	// 处理进位
//	for (int i = 0; i < lc; i++)
//	{
//		c[i + 1] += c[i] / 10;
//		c[i] %= 10;
//	}
//	// 处理前导零
//	while (lc > 1 && c[lc - 1] == 0) lc--;
//}
//int main()
//{
//	string x, y; cin >> x >> y;
//	// 1. 拆分每⼀位，逆序放在数组中
//	la = x.size(); lb = y.size(); lc = la + lb;
//	for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
//	for (int i = 0; i < lb; i++) b[lb - 1 - i] = y[i] - '0';
//	// 2. 模拟乘法的过程
//	mul(c, a, b); // c = a * b
//	// 输出结果
//	for (int i = lc - 1; i >= 0; i--) cout << c[i];
//	return 0;
//}

// ⾼精度除法
// https://www.luogu.com.cn/problem/P1480
//#include <iostream>
//using namespace std;
//const int N = 1e6 + 10;
//typedef long long LL;
//int a[N], b, c[N];
//int la, lc;
//// ⾼精度除法的模板 - c = a / b （⾼精度 / 低精度）
//void sub(int c[], int a[], int b)
//{
//	LL t = 0; // 标记每次除完之后的余数
//	for (int i = la - 1; i >= 0; i--)
//	{
//		// 计算当前的被除数
//		t = t * 10 + a[i];
//		c[i] = t / b;
//		t %= b;
//	}
//	// 处理前导 0
//	while (lc > 1 && c[lc - 1] == 0) lc--;
//}
//int main()
//{
//	string x; cin >> x >> b;
//	la = x.size();
//	for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';
//	// 模拟除法的过程
//	lc = la;
//	sub(c, a, b); // c = a / b
//	for (int i = lc - 1; i >= 0; i--) cout << c[i];
//	return 0;
//}

//string s;
//
//// 生成好的前缀函数
//int pi[N];
//
////  长度为 i 的前缀中，所有 border 的长度
//void get_border(int i)
//{
//	int j = pi[i];
//	while (j)
//	{
//		cout << j;
//		j = pi[j];
//	}
//}

//string s;
//int pi[N];
//
//void get_pi(int i)
//{
//	cin >> s;
//	int n = s.size();
//	s = ' ' + s;
//
//	for (int i = 2; i <= n; i++)
//	{
//		int j = pi[i - 1];
//		while (j && s[i] != s[j + 1]) j = pi[j];
//		if (s[i] == s[j + 1]) j++;
//		pi[i] = j;
//	}
//
//	for (int i = 2, j = 0; i <= n; i++)
//	{
//		while (j && s[i] != s[j + 1]) j = pi[j];
//		if (s[i] == s[j + 1]) j++;
//		pi[i] = j;
//	}
//}

//#include <iostream>
//#include <string>
//using namespace std;
//
//const int N = 2e6 + 10;
//
//string s, t;
//int n, m;
//int pi[N];
//
//int main()
//{
//	cin >> s >> t;
//	n = s.size(); 
//	m = t.size();
//
//	s = ' ' + t + '#' + s;
//
//	for (int i = 2; i <= n + m + 1; i++)
//	{
//		int j = pi[i - 1];
//		while (j && s[j + 1] != s[i]) j = pi[j];
//		if (s[j + 1] == s[i]) j++;
//		pi[i] = j;
//
//		if (j == m)
//		{
//			cout << i - 2 * m << endl;
//		}
//	}
//
//	for (int i = 1; i <= m; i++) cout << pi[i] << " ";
//	cout << endl;
//
//	return 0;
//}

#include <iostream>
#include <string>
using namespace std;

const int N = 2e6 + 10;

string s, t;
int n, m;
int ne[N];

int main()
{

	cin >> s >> t;
	n = s.size(); 
	m = t.size();
	s = ' ' + s; 
	t = ' ' + t;
	// 预处理模式串的 next 数组
	for (int i = 2, j = 0; i <= m; i++)
	{
		while (j && t[i] != t[j + 1]) j = ne[j];
		if (t[i] == t[j + 1]) j++;
		ne[i] = j;
	}
	// 利⽤ next 数组匹配
	for (int i = 1, j = 0; i <= n; i++)
	{
		while (j && s[i] != t[j + 1]) j = ne[j];
		if (s[i] == t[j + 1]) j++;
		if (j == m)
		{
			cout << i - m + 1 << endl;
		}
	}

	for (int i = 1; i <= m; i++) cout << ne[i] << " ";
	cout << endl;

	return 0;
}

